package models;

import java.util.List;

import play.db.ebean.Model;
import play.db.ebean.Model.Finder;

import javax.persistence.*;

import com.avaje.ebean.Page;
import com.avaje.ebean.validation.NotNull;

@Entity
public class Subcompartment extends Model{
	
	@Id
	public Long id;
	
	@NotNull
	public String subcompartmentKey;
	
	@NotNull
	public Integer area;	//square meter(输入输出时转换，程序中运算当作平方米)
	
	@ManyToOne
	@NotNull
	public Compartment compartment;
	
	@OneToOne
	@NotNull
	public LandCategory landCategory;
	
	@OneToOne
	@NotNull
	public ForestrySubType forestrySubtype;
	
	@OneToOne
	@NotNull
	public Management management;
	
	@OneToOne
	@NotNull
	public Origon origon;
	
	@NotNull
	public Short naturalness;

	@OneToOne
	@NotNull
	public Ecosystem ecosystem;
	
	@OneToOne
	@NotNull
	public ScatteredTrees scatteredTrees;
	
	@OneToOne
	@NotNull
	public Soil soil;
	
	@OneToOne
	@NotNull
	public Geomorphology geomorphology;
	
	@OneToOne
	@NotNull
	public Country position;

	//Finder
	public static Finder<Long, Subcompartment> find = new Finder<Long, Subcompartment>(
			Long.class, Subcompartment.class);
	
	public static Subcompartment getSubcompartment(Subcompartment subcompartment) {
		return find.fetch("subcompartment").where().idEq(subcompartment.id).findUnique();
	}
	
    /**
     * Return a page of Subcompartment
     *
     * @param page Page to display
     * @param pageSize Number of computers per page
     * @param sortBy Computer property used for sorting
     * @param order Sort order (either or asc or desc)
     * @param filter Filter applied on the name column
     */
	
    public static Page<Subcompartment> page(int page, int pageSize, String sortBy, String order, String filter) {
        return 
            find.where()
                .ilike("name", "%" + filter + "%")
                .orderBy(sortBy + " " + order)
                .fetch("compartment")
                .findPagingList(pageSize)
                .getPage(page);
    }
    
    /* 算法 */
    /*平均年龄
     *单位面积蓄积量
     *估计值方差
     *标准误差
     *总蓄积量算法
     *郁闭度
     *龄级
     */
    
    /*未完成
     *地位级 
     */
    
    public double averageAge(){
    	//计算平均年龄
    	List<Plot> plot = Plot.find.where().eq("subcompartment", this).findList();
    	double averageAge = 0;

    	for( int i = 0; i < plot.size(); i++ ){
    		//plot area 改成 林场下的
    		averageAge += plot.get(i).averageAge();
    	}
    	
    	return averageAge/plot.size();
    }
    
   	public Float volumePerHa(){
		//单位面积蓄积量
		List<Plot> plot = Plot.find.where().eq("subcompartment", this).findList();
		Float volume = 0F;
		
		for( int i = 0; i < plot.size(); i++ ){
			volume += plot.get(i).volumePerHa();
		}
		
		return volume/plot.size();
	}
   	
   	public Float volume(){
		//总蓄积量
		return this.volumePerHa()*this.area;
	}
	
	public Float volumeEstimatorVariance(){
		//估计值方差
		Float ans = 0F;
		Float Ya = this.volumePerHa();
		List <Plot> y = Plot.find.where().eq("subcompartment", this).findList();
		
		int n = y.size();
		
		for( int i = 0; i < n; i++ ){
			ans += (y.get(i).volumePerHa() - Ya) * (y.get(i).volumePerHa() - Ya);
		}
		ans = ans /(n*(n-1));
		return ans;
	}
	
	public Float volumeStandardDeviation(){
		//标准误差
		return (float) Math.sqrt(this.volumeEstimatorVariance());
	}
	
	public Float canopyDensity(){
		//郁闭度
		Float canopyDensity = 0F;
		List<Plot> plot = Plot.find.where().eq("plot", this).findList();
		for( int i = 0; i < plot.size(); i++ ){
			canopyDensity += plot.get(i).canopyDensity;
		}
		return canopyDensity/plot.size();
	}
	
	public Integer ageClass(){
		//龄级
		int age = (int)this.averageAge();  //可能出现bug
		
		age /= 10; //取十位数
		
		if( age % 2 == 1 ){
			return age * 10; //为奇
		}
		else{
			return (++age) * 10;
		}
		
	}
}

